home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /** header ******************************************************************/
-
- /*
- // $Id: pick2d.c,v 1.1 1994/02/11 18:49:16 brettb Exp $
- //
- // Title: pick2d.c -- demonstrate 2d picking in a mixed model program.
- // Keywords: IrisGL.Prod, IrisGL.Examples, Mixed, glx, picking
- // Viewable: No
- //
- // Description:
- // This is a mixed model port of an IrisGL program which does 2d
- // picking using the pick() function.
- //
- // Operation:
- // Move the cursor over the blue edges or red vertices and click
- // with the left mouse button to select things. What is returned
- // in the name buffer is displayed. The pick size is 8 x 8 pixels.
- // Depending on where you pick near a vertex you can get:
- // - just the vertex;
- // - the vertex and one adjoining edge;
- // - or the vertex and both adjoining edges.
- //
- // Compilation:
- // cc -float -prototypes -DFUNCPROTO -O pick2d.c -o pick2d \
- // -s -lXirisw -lXm -lXt -lgl -lX11 -lm -lPW
- */
-
- /** notes *******************************************************************/
- /** includes ****************************************************************/
-
- #include <stdio.h> /* printf, ... */
- #include <Xm/Xm.h> /* for motif */
- #include <Xm/Form.h> /* motif widget */
- #include <Xm/Frame.h> /* motif widget */
- #include <Xm/PushB.h> /* motif widget */
- #include <Xm/RowColumn.h> /* motif widget */
- #include <Xm/Separator.h> /* motif widget */
- #include <X11/Xirisw/GlxMDraw.h> /* gl widget */
-
- /** defines *****************************************************************/
-
- /* limits */
- #define NAME_BUF_SIZE 50
-
- /* colors */
- #define RGB_BLACK 0x00000000
- #define RGB_RED 0x000000FF
- #define RGB_WHITE 0x00FFFFFF
- #define RGB_BLUE 0x00FF0000
-
- /* window values -- 2:1 */
- #define WIN_L -0.5
- #define WIN_R 199.5
- #define WIN_B -0.5
- #define WIN_T 99.5
-
- /* pick group layout */
- #define POLY_GROUP 0
- #define EDGE_GROUP 1
- #define VERT_GROUP 2
-
- /** prototypes **************************************************************/
-
- /* setup */
- static void check_capabilities(void);
- static void install_colormaps(Widget top_level, Widget glw);
-
- /* gl callbacks and support */
- static void gl_ginit_cb(Widget w, XtPointer appdat, XtPointer sysdat);
- static void gl_expose_cb(Widget w, XtPointer appdat, XtPointer sysdat);
- static void gl_resize_cb(Widget w, XtPointer appdat, XtPointer sysdat);
- static void gl_input_cb(Widget w, XtPointer appdat, XtPointer sysdat);
-
- /* misc callbacks */
- static void quit_cb(Widget w, XtPointer appdat, XtPointer sysdat);
-
- /* tests */
- static void pick_test(void);
-
- /* drawing */
- static void draw_frame(void);
- static void draw_items(void);
- static void draw_poly(int poly_index);
- static void draw_hit_lists(short name_buffer[], long nhitlists);
-
- /** typedefs ****************************************************************/
- /** variables ***************************************************************/
-
- /*
- // mixed-model configuration:
- */
- static GLXconfig glx_config[] = {
- {GLX_NORMAL, GLX_RGB, TRUE},
- {GLX_NORMAL, GLX_DOUBLE, TRUE},
- { 0, 0, 0 },
- };
-
- /* picking results */
- static long nhitlists = 0;
- static short name_buffer[NAME_BUF_SIZE];
- static char *pick_group[] = {
- "poly", "edge", "vert"
- };
-
- /** functions ***************************************************************/
-
- /*
- // main - program entry point.
- */
- void main(int argc, char *argv[])
- {
- XtAppContext app_context; /* application context */
- Display *dsp; /* display ref */
- Widget app_shell; /* first widget */
- Widget form; /* surrounds app */
- Widget rowcol; /* manages input buttons */
- Widget button; /* quit button */
- Widget separator; /* between input and output */
- Widget frame; /* to surround gl widget */
- Widget glw; /* can do gl rendering in this guy */
- Arg args[15]; /* for name/value pairs */
- int n; /* reusable indices */
-
- /* make sure we can we do it */
- check_capabilities();
-
- /* initialize toolkit, creating application shell */
- n = 0;
- XtSetArg(args[n], XmNtitle, "Pick Demo"); n++;
- app_shell = XtAppInitialize(
- &app_context, "Pick", NULL, 0, &argc, argv, NULL, args, n
- );
-
- /* create container for app */
- n = 0;
- form = XmCreateForm(app_shell, "form", args, n);
- XtManageChild(form);
-
- /* create the command area */
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
- rowcol = XmCreateRowColumn(form, "rowcol", args, n);
- XtManageChild(rowcol);
-
- /* create the command area buttons */
- n = 0;
- button = XmCreatePushButton(rowcol, "Quit", args, n);
- XtAddCallback(button, XmNactivateCallback, quit_cb, NULL);
- XtManageChild(button);
-
- /* create separator between command area and output area */
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, rowcol); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
- separator = XmCreateSeparator(form, "separator", args, n);
- XtManageChild(separator);
-
- /* create the output area */
- /* create the frame */
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- XtSetArg(args[n], XmNleftWidget, separator); n++;
- XtSetArg(args[n], XmNleftOffset, 5); n++;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNrightOffset, 5); n++;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNbottomOffset, 5); n++;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
- XtSetArg(args[n], XmNtopOffset, 5); n++;
- XtSetArg(args[n], XmNshadowThickness, 6); n++;
- frame = XmCreateFrame(form, "frame", args, n);
- XtManageChild(frame);
-
- /* create the gl widget */
- n = 0;
- XtSetArg(args[n], GlxNglxConfig, glx_config); n++;
- XtSetArg(args[n], XmNborderWidth, 0); n++;
- XtSetArg(args[n], XmNwidth, 800); n++;
- XtSetArg(args[n], XmNheight, 400); n++;
- glw = GlxCreateMDraw(frame, "glw", args, n);
- XtManageChild(glw);
- XtAddCallback(glw, GlxNexposeCallback, gl_expose_cb, 0);
- XtAddCallback(glw, GlxNresizeCallback, gl_resize_cb, 0);
- XtAddCallback(glw, GlxNginitCallback, gl_ginit_cb, 0);
- XtAddCallback(glw, GlxNinputCallback, gl_input_cb, 0);
-
- /* realize the app, creating the actual x windows */
- XtRealizeWidget(app_shell);
- install_colormaps(app_shell, glw);
-
- /* enter the event loop */
- XtAppMainLoop(app_context);
- }
-
-
- /*- support: setup ---------------------------------------------------------*/
- /*
- // check_capabilities - find out if the machine can do what we need.
- */
- static void check_capabilities(void)
- {
- if (getgdesc(GD_BITS_NORM_DBL_RED) == 0) {
- fprintf(stderr, "Double buffered RGB mode not available.\n");
- exit(1);
- }
- }
-
-
- /*
- // install_colormaps - let the window manager know about our colormaps.
- //
- // This has been generalized to handle any windows a gl widget might have.
- // It may not necessarily being using any of them.
- */
- static void install_colormaps(Widget top_level, Widget glw)
- {
- Window overlay_win, popup_win, underlay_win;
- Window window[5];
- int i;
-
- XtVaGetValues(
- glw,
- GlxNoverlayWindow, &overlay_win,
- GlxNpopupWindow, &popup_win,
- GlxNunderlayWindow, &underlay_win,
- NULL
- );
- i = 0;
- if (overlay_win)
- window[i++] = overlay_win;
- if (popup_win)
- window[i++] = popup_win;
- if (underlay_win)
- window[i++] = underlay_win;
- window[i++] = XtWindow(glw);
- window[i++] = XtWindow(top_level);
- XSetWMColormapWindows(XtDisplay(top_level), XtWindow(top_level), window, i);
- }
-
-
- /*- support: callbacks (gl widget) -----------------------------------------*/
- /*
- // gl_ginit_cb - perform any necessary graphics initialization.
- */
- static void gl_ginit_cb(Widget w, XtPointer appdat, XtPointer sysdat)
- {
- GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) sysdat;
-
- GLXwinset(XtDisplay(w), XtWindow(w));
- mmode(MVIEWING);
- ortho2(WIN_L, WIN_R, WIN_B, WIN_T);
- }
-
-
- /*
- // gl_expose_cb - handle expose events for the gl widget.
- */
- static void gl_expose_cb(Widget w, XtPointer appdat, XtPointer sysdat)
- {
- GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) sysdat;
-
- GLXwinset(XtDisplay(w), XtWindow(w));
- draw_frame();
- }
-
-
- /*
- // gl_resize_cb - handle resize events for the gl widget.
- */
- static void gl_resize_cb(Widget w, XtPointer appdat, XtPointer sysdat)
- {
- GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) sysdat;
-
- GLXwinset(XtDisplay(w), XtWindow(w));
- viewport(0, glx->width-1, 0, glx->height-1);
- }
-
-
- /*
- // gl_input_cb - handle input from a gl window.
- */
- static void gl_input_cb(Widget w, XtPointer appdat, XtPointer sysdat)
- {
- GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) sysdat;
-
- GLXwinset(XtDisplay(w), XtWindow(w));
- switch (glx->event->type) {
- case ButtonPress:
- /* we will pick on the release */
- break;
- case ButtonRelease:
- pick_test();
- break;
- }
- }
-
-
- /*- support: callbacks (misc) ----------------------------------------------*/
- /*
- // quit_cb - exit the application.
- */
- static void quit_cb(Widget w, XtPointer appdat, XtPointer sysdat)
- {
- exit(0);
- }
-
-
- /*- support: picking and selecting -----------------------------------------*/
- /*
- // pick_test - try picking items which draw_items() displays.
- */
- static void pick_test(void)
- {
- pushmatrix();
- picksize(8, 8);
- pick(name_buffer, NAME_BUF_SIZE);
- ortho2(WIN_L, WIN_R, WIN_B, WIN_T);
- initnames();
- draw_items();
- gflush();
- nhitlists = endpick(name_buffer);
- ortho2(WIN_L, WIN_R, WIN_B, WIN_T);
- popmatrix();
- draw_frame();
- }
-
-
- /*- support: drawing -------------------------------------------------------*/
- /*
- // draw_frame - render the next frame.
- */
- static void draw_frame(void)
- {
- cpack(RGB_BLACK);
- clear();
- draw_items();
- draw_hit_lists(name_buffer, nhitlists);
- swapbuffers();
- gflush();
- }
-
-
- /*
- // draw_items - draw a couple of polygons.
- */
- static void draw_items(void)
- {
- loadname(0);
- pushmatrix();
- draw_poly(0);
- translate(100.0, 0.0, 0.0);
- draw_poly(1);
- popmatrix();
- }
-
-
- /*
- // draw_poly - draw a single polygon.
- //
- // This names each polygon, each polygon edge, and each polygon vertex for
- // the purposes of picking.
- */
- static void draw_poly(int poly_index)
- {
- static float poly_pt[][2] = { /* describe pentagon */
- {25.0, 25.0},
- {75.0, 25.0},
- {90.0, 60.0},
- {50.0, 85.0},
- {10.0, 60.0},
- /**/
- {25.0, 25.0}, /* wrap around to first point */
- };
- int i; /* loop index */
-
- /* name polygon */
- pushname(POLY_GROUP); /* this is a polygon */
- pushname(poly_index); /* this is its name */
-
- /* draw edges in blue */
- pushname(EDGE_GROUP); /* these are edges */
- linewidth(4); /* make them all look big */
- cpack(RGB_BLUE);
- for (i=0; i<5; i++) {
- pushname(i); /* this is their subname: 0,1,2,... */
- bgnline();
- v2f(poly_pt[i+0]);
- v2f(poly_pt[i+1]);
- endline();
- popname();
- }
- linewidth(1);
- popname();
-
- /* draw vertices in red */
- cpack(RGB_RED);
- pushname(VERT_GROUP); /* these are vertices */
- for (i=0; i<5; i++) {
- pushname(i); /* this is their subname: 0,1,2,... */
- circf(poly_pt[i][0], poly_pt[i][1], 2.0);
- popname();
- }
- popname();
-
- popname();
- popname();
- }
-
-
- /*
- // draw_hit_lists - display the hit lists for a polygon, interpreting
- // the hit list names so they having more meaning to our polygon.
- //
- // all of our returned names lists will be of the format:
- // <poly_group, poly_sub_index, edge_group, edge_sub_index>
- // or
- // <poly_group, poly_sub_index, vert_group, vert_sub_index>
- //
- // thus all of our names lists should be of length 4.
- //
- */
- static void draw_hit_lists(short name_buffer[], long nhitlists)
- {
- char str[50]; /* for building strings */
- int list; /* index of the current name list */
- int nitems; /* size of the current list */
- int index; /* scans uniformly through buffer[] */
- int tx, ty, tdy; /* simple text cursor */
- int i; /* index */
-
- tx = 70;
- ty = 16;
- tdy = 4;
-
- cpack(RGB_WHITE);
- cmov2i(tx, ty);
- sprintf(str, "%ld name list", nhitlists);
- charstr(str);
- if (nhitlists != 1)
- charstr("s");
- if (nhitlists > 0)
- charstr(": ");
- index = 0;
- for (list=0; list<nhitlists; list++) {
- ty -= tdy; /* drop down one text line */
- cmov2i(tx, ty);
- sprintf(str, "list %d: ", list);
- charstr(str);
- nitems = name_buffer[index++];
- index++; /* skip... */
- nitems--; /* ...loadname(0) */
- for (i=0; i<nitems; i+=2) {
- sprintf(str, "[%s %d] ",
- pick_group[name_buffer[index]],
- name_buffer[index+1]
- );
- charstr(str);
- index += 2;
- }
- }
- }
-
- /** eof *********************************************************************/
-